package com.cq.hd.member.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.cq.hd.common.enums.biz.AgentBindApplyAuditStateEnum;
import com.cq.hd.common.enums.biz.AuditStateEnum;
import com.cq.hd.common.pagination.Page;
import com.cq.hd.common.response.Throw;
import com.cq.hd.member.api.dto.*;
import com.cq.hd.member.api.vo.AgentUnBindApplyPageVo;
import com.cq.hd.member.api.vo.MyAgentVo;
import com.cq.hd.member.mapper.*;
import com.cq.hd.member.po.*;
import com.cq.hd.member.service.TbAgentUnBindApplyService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.interceptor.DefaultTransactionAttribute;
import org.springframework.util.CollectionUtils;

import java.time.LocalDateTime;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * <p>
 * 经纪人解绑申请记录 服务实现类
 * </p>
 */
@Slf4j
@Service
public class TbAgentUnBindApplyServiceImpl extends ServiceImpl<TbAgentUnBindApplyMapper, TbAgentUnBindApplyPo> implements TbAgentUnBindApplyService {

    @Autowired
    private TbAppUserMapper appUserMapper;

    @Autowired
    private PlatformTransactionManager transactionManager;

    @Autowired
    private TbBusinessAgentMapper businessAgentMapper;

    @Autowired
    private TbBusinessAgentBindRecordMapper businessAgentBindRecordMapper;

    @Autowired
    private TbAgentBindApplyMapper agentBindApplyMapper;

    /**
     * 经纪人解绑申请
     */
    @Override
    public Boolean apply(AgentUnBindApplyDto agentUnbindApplyDto) {
        MyAgentVo myAgentVo = businessAgentMapper.myParentAgent(agentUnbindApplyDto.getUserId());
        // 如果没有上级经纪人，直接返回成功
        if (myAgentVo == null) {
            Throw.isBusinessException("当前没有绑定的经纪人");
            return true;
        }

        TbAgentUnBindApplyPo po = baseMapper.getWaitAuditByApplyUserId(agentUnbindApplyDto.getUserId());
        if (po != null) {
            Throw.isBusinessException("你有待审核的记录，请勿重复申请");
        }

        // 获取绑定申请通过的记录，最新一条
        TbAgentBindApplyPo applyPo = agentBindApplyMapper.selectOne(new QueryWrapper<TbAgentBindApplyPo>()
                .eq("inviter_user_id", myAgentVo.getAgentId())
                .eq("apply_user_id", myAgentVo.getUserId())
                .eq("audit_state", AuditStateEnum.SUCCESS.getValue())
                .orderByDesc("id")
                .last("limit 1"));
        if (applyPo == null) {
            log.error("未找到入驻申请记录：" + myAgentVo);
            Throw.isBusinessException("未找到入驻申请记录");
        }

        TbAgentUnBindApplyPo tbAgentUnBindApplyPo = new TbAgentUnBindApplyPo();
        tbAgentUnBindApplyPo.setApplyUserId(agentUnbindApplyDto.getUserId());
        tbAgentUnBindApplyPo.setInviterUserId(myAgentVo.getAgentId());
        tbAgentUnBindApplyPo.setAgentLevel(2);
        tbAgentUnBindApplyPo.setBusinessId(0L);
        tbAgentUnBindApplyPo.setAgentId(myAgentVo.getAgentId());
        tbAgentUnBindApplyPo.setMobile(applyPo.getMobile());
        tbAgentUnBindApplyPo.setUsername(applyPo.getUsername());
        tbAgentUnBindApplyPo.setGroupId(myAgentVo.getGroupId());
        tbAgentUnBindApplyPo.setAuditState(AgentBindApplyAuditStateEnum.AUDIT_PENDING.getValue());
        tbAgentUnBindApplyPo.setApplyReason(agentUnbindApplyDto.getApplyReason());
        tbAgentUnBindApplyPo.setCreateTime(LocalDateTime.now());
        tbAgentUnBindApplyPo.setUpdateTime(LocalDateTime.now());
        save(tbAgentUnBindApplyPo);

        // 老板变卦，解绑申请不用审核，那这里直接帮他审核通过
        AgentUnBindApplyAuditDto agentUnBindApplyAuditDto = new AgentUnBindApplyAuditDto();
        agentUnBindApplyAuditDto.setId(tbAgentUnBindApplyPo.getId());
        agentUnBindApplyAuditDto.setInviterUserId(tbAgentUnBindApplyPo.getInviterUserId());
        agentUnBindApplyAuditDto.setAuditState(AgentBindApplyAuditStateEnum.AUDIT_PASS.getValue());
        audit(agentUnBindApplyAuditDto);

        return true;
    }

    @Override
    public Integer waitAuditCount(Long inviterUserId) {
        return baseMapper.getWaitAuditCount(inviterUserId);
    }

    @Override
    public Page<AgentUnBindApplyPageVo> page(AgentUnBindApplyPageDto agentUnBindApplyPageDto) {
        PageHelper.startPage(agentUnBindApplyPageDto.getPageNum(), agentUnBindApplyPageDto.getPageSize());
        List<AgentUnBindApplyPageVo> agentUnBindApplyPos = baseMapper.listByDto(agentUnBindApplyPageDto);
        if (CollectionUtils.isEmpty(agentUnBindApplyPos)) {
            return new Page<>();
        }

        // 申请人id
        List<Long> userIds = agentUnBindApplyPos.stream().map(AgentUnBindApplyPageVo::getApplyUserId).collect(Collectors.toList());
        Map<Long, TbAppUserPo> appUserMap = new HashMap<>();
        List<TbAppUserPo> appUserPos = appUserMapper.selectList(new QueryWrapper<TbAppUserPo>()
                .in("id", userIds));
        if (!CollectionUtils.isEmpty(appUserPos)) {
            appUserMap = appUserPos.stream()
                    .collect(Collectors.toMap(TbAppUserPo::getId, Function.identity()));
        }

        Map<Long, TbAppUserPo> finalAppUserMap = appUserMap;
        agentUnBindApplyPos.forEach(vo -> {
            TbAppUserPo appUserPo = finalAppUserMap.get(vo.getApplyUserId());
            if (appUserPo != null) {
                vo.setNickName(appUserPo.getNickName());
                vo.setAvatar(appUserPo.getAvatar());
            }
        });

        PageInfo<AgentUnBindApplyPageVo> pageInfo = new PageInfo<>(agentUnBindApplyPos);
        return Page.newPageWithAllFields(pageInfo.getList(), pageInfo.getPageNum(), pageInfo.getPageSize(), pageInfo.getTotal(), pageInfo.getPages());
    }

    @Override
    public Boolean audit(AgentUnBindApplyAuditDto agentUnBindApplyAuditDto) {
        AgentUnBindApplyDto dto = new AgentUnBindApplyDto();
        dto.setId(agentUnBindApplyAuditDto.getId());
        dto.setInviterUserId(agentUnBindApplyAuditDto.getInviterUserId());
        TbAgentUnBindApplyPo po = baseMapper.getByDto(dto);
        if (po == null) {
            Throw.isBusinessException("解绑申请记录不存在");
        }

        if (!Objects.equals(po.getAuditState(), AgentBindApplyAuditStateEnum.AUDIT_PENDING.getValue())) {
            Throw.isBusinessException("该解绑申请已经审核过");
        }

        String refuseReason = agentUnBindApplyAuditDto.getRefuseReason();
        if (Objects.equals(po.getAuditState(), AgentBindApplyAuditStateEnum.AUDIT_REJECT.getValue())) {
            if (refuseReason == null || refuseReason.isEmpty()) {
                Throw.isBusinessException("请输入审核不通过理由");
            }
        }

        Long userId = po.getApplyUserId();
        TbAppUserPo tbAppUserPo = appUserMapper.selectById(userId);
        if (tbAppUserPo == null || tbAppUserPo.getDelState() != 0) {
            Throw.isBusinessException("未找到用户数据");
        }

        Long businessId = 0L;
        Long agentId = 0L;
        if (po.getAgentLevel() == 1) {
            businessId = po.getBusinessId();
        } else {
            agentId = po.getInviterUserId();
        }

        // 是否已经有对应的绑定记录
        TbBusinessAgentPo businessAgentPo = businessAgentMapper.getBusinessAgentRecord(businessId, agentId, userId);
        if (businessAgentPo == null) {
            Throw.isBusinessException("找不到绑定记录，无法解绑");
        }

        TransactionStatus transaction = transactionManager.getTransaction(new DefaultTransactionAttribute());

        LocalDateTime now = LocalDateTime.now();
        try {
            po.setAuditState(agentUnBindApplyAuditDto.getAuditState());
            po.setRefuseReason(refuseReason);
            po.setAuditTime(now);
            baseMapper.updateById(po);

            // 审核通过，解绑
            if (Objects.equals(po.getAuditState(), AgentBindApplyAuditStateEnum.AUDIT_PASS.getValue())) {
                businessAgentPo.setDelState(1);
                businessAgentPo.setUpdateTime(now);
                int update = businessAgentMapper.updateById(businessAgentPo);
                if (update == 0) {
                    log.error("[审核经纪人解绑申请失败]userId:{}, agentId:{}, businessId:{}", userId, agentId, businessId);
                    Throw.isBusinessException("审核失败");
                }

                tbAppUserPo.setAgentId(0L);
                tbAppUserPo.setUpdateTime(now);
                update = appUserMapper.updateById(tbAppUserPo);
                if (update == 0) {
                    log.error("经纪人解绑申请审核,更新经纪人状态失败,userId:{}, businessId:{}, agentId:{}", userId, businessId, agentId);
                    Throw.isBusinessException("审核失败");
                }
            }

            transactionManager.commit(transaction);
        } catch (Exception e) {
            // 回滚事务
            transactionManager.rollback(transaction);
            log.error("<经纪人解绑驻申请审核>事务异常回滚", e);
            Throw.isBusinessException("审核失败");
            return false;
        }

        return true;
    }
}
